home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / dpmi.asm < prev    next >
Encoding:
Assembly Source File  |  1997-01-16  |  15.9 KB  |  633 lines

  1. ;*      DPMI.ASM
  2. ;*
  3. ;* DPMI functions for protected mode MIDAS
  4. ;*
  5. ;* $Id: dpmi.asm,v 1.3 1997/01/16 18:41:59 pekangas Exp $
  6. ;*
  7. ;* Copyright 1996,1997 Housemarque Inc.
  8. ;*
  9. ;* This file is part of the MIDAS Sound System, and may only be
  10. ;* used, modified and distributed under the terms of the MIDAS
  11. ;* Sound System license, LICENSE.TXT. By continuing to use,
  12. ;* modify or distribute this file you indicate that you have
  13. ;* read the license and understand and accept it fully.
  14. ;*
  15.  
  16. P386
  17. IDEAL
  18. JUMPS
  19.  
  20.  
  21. INCLUDE "lang.inc"
  22. INCLUDE "errors.inc"
  23. INCLUDE "dpmi.inc"
  24.  
  25.  
  26.  
  27. CODESEG
  28.  
  29.  
  30.  
  31. ;/***************************************************************************\
  32. ;*
  33. ;* Function:    int dpmiAllocDescriptor(unsigned *descriptor);
  34. ;*
  35. ;* Description: Allocate LDT descriptor. Use dpmiFreeDescriptor to deallocate.
  36. ;*
  37. ;* Input:       unsigned *descriptor    pointer to descriptor number
  38. ;*
  39. ;* Returns:     MIDAS error code. Descriptor number is written to *descriptor.
  40. ;*
  41. ;\***************************************************************************/
  42.  
  43. PROC    dpmiAllocDescriptor     _funct  descriptor : _ptr
  44. USES    _bx
  45.  
  46.         xor     _ax,_ax                 ; DPMI function 0 - alloc LDT descr.
  47.         mov     _cx,1                   ; allocate one descriptor
  48.         int     31h
  49.         jc      @@err
  50.  
  51. IFDEF __32__
  52.         and     eax,0FFFFh
  53. ENDIF
  54.  
  55.         LOADPTR es,_bx,[descriptor]     ; write allocated descriptor to
  56.         mov     [_esbx],_ax             ; *descriptor
  57.  
  58.         xor     _ax,_ax
  59.         jmp     @@done
  60.  
  61. @@err:
  62.         mov     _ax,errDPMIFailure
  63.         ERROR   ID_dpmiAllocDescriptor
  64.  
  65. @@done:
  66.         ret
  67. ENDP
  68.  
  69.  
  70.  
  71.  
  72. ;/***************************************************************************\
  73. ;*
  74. ;* Function:    int dpmiFreeDescriptor(unsigned descriptor);
  75. ;*
  76. ;* Description: Deallocates an LDT descriptor.
  77. ;*
  78. ;* Input:       unsigned descriptor     descriptor to deallocate
  79. ;*
  80. ;* Returns:     MIDAS error code
  81. ;*
  82. ;\***************************************************************************/
  83.  
  84. PROC    dpmiFreeDescriptor      _funct  descriptor : _int
  85. USES    _bx
  86.  
  87.         mov     _ax,0001h               ; DPMI function 1 - free LDT descr.
  88.         mov     _bx,[descriptor]
  89.         int     31h
  90.         jc      @@err
  91.  
  92.         xor     _ax,_ax
  93.         jmp     @@done
  94.  
  95. @@err:
  96.         mov     _ax,errInvalidDescriptor
  97.         ERROR   ID_dpmiFreeDescriptor
  98.  
  99. @@done:
  100.         ret
  101. ENDP
  102.  
  103.  
  104.  
  105.  
  106. ;/***************************************************************************\
  107. ;*
  108. ;* Function:    int dpmiSetSegmentBase(unsigned selector, ulong baseAddr);
  109. ;*
  110. ;* Description: Changes the 32-bit linear base address of a selector.
  111. ;*
  112. ;* Input:       unsigned selector       selector number
  113. ;*              ulong baseAddr          32-bit linear base address for
  114. ;*                                      selector
  115. ;*
  116. ;* Returns:     MIDAS error code.
  117. ;*
  118. ;\***************************************************************************/
  119.  
  120. PROC    dpmiSetSegmentBase      _funct  selector : _int, baseAddr : _long
  121. USES    _bx
  122.  
  123.         mov     _ax,0007h               ; DPMI function 7 - set segment base
  124.         mov     _bx,[selector]
  125. IFDEF __32__
  126.         xor     ecx,ecx
  127.         xor     edx,edx
  128. ENDIF
  129.         mov     cx,[word baseAddr+2]    ; cx:dx = new base address
  130.         mov     dx,[word baseAddr]
  131.         int     31h
  132.         jc      @@err
  133.  
  134.         xor     _ax,_ax
  135.         jmp     @@done
  136.  
  137. @@err:
  138.         mov     _ax,errInvalidDescriptor
  139.         ERROR   ID_dpmiSetSegmentBase
  140.  
  141. @@done:
  142.         ret
  143. ENDP
  144.  
  145.  
  146.  
  147.  
  148. ;/***************************************************************************\
  149. ;*
  150. ;* Function:    int dpmiGetSegmentBase(unsigned selector, ulong *baseAddr);
  151. ;*
  152. ;* Description: Reads the 32-bit linear base address of a selector.
  153. ;*
  154. ;* Input:       unsigned selector       selector number
  155. ;*              ulong *baseAddr         pointer to the 32-bit linear base
  156. ;*                                      address of the selector
  157. ;*
  158. ;* Returns:     MIDAS error code. Selector base address is written to
  159. ;*              *baseAddr.
  160. ;*
  161. ;\***************************************************************************/
  162.  
  163. PROC    dpmiGetSegmentBase      _funct  selector : _int, baseAddr : _ptr
  164. USES    _bx
  165.  
  166.         mov     _ax,0006h               ; DPMI function 7 - get segment base
  167.         mov     _bx,[selector]
  168.         int     31h
  169.         jc      @@err
  170.  
  171.         LOADPTR es,_bx,[baseAddr]
  172.         mov     [word _esbx],dx         ; write segment base address to
  173.         mov     [word _esbx+2],cx       ; *baseAddr
  174.  
  175.         xor     _ax,_ax
  176.         jmp     @@done
  177.  
  178. @@err:
  179.         mov     _ax,errInvalidDescriptor
  180.         ERROR   ID_dpmiGetSegmentBase
  181.  
  182. @@done:
  183.         ret
  184. ENDP
  185.  
  186.  
  187.  
  188.  
  189. ;/***************************************************************************\
  190. ;*
  191. ;* Function:    int dpmiSetSegmentLimit(unsigned selector, ulong limit);
  192. ;*
  193. ;* Description: Changes the limit of a segment selector.
  194. ;*
  195. ;* Input:       unsigned selector       selector number
  196. ;*              ulong limit             32-bit segment limit
  197. ;*
  198. ;* Returns:     MIDAS error code.
  199. ;*
  200. ;\***************************************************************************/
  201.  
  202. PROC    dpmiSetSegmentLimit     _funct  selector : _int, limit : _long
  203. USES    _bx
  204.  
  205.         mov     _ax,0008h               ; DPMI function 8 - set segment limit
  206.         mov     _bx,[selector]
  207. IFDEF __32__
  208.         xor     ecx,ecx
  209.         xor     edx,edx
  210. ENDIF
  211.         mov     cx,[word limit+2]       ; cx:dx = new segment limit
  212.         mov     dx,[word limit]
  213.         int     31h
  214.         jc      @@err
  215.  
  216.         xor     _ax,_ax
  217.         jmp     @@done
  218.  
  219. @@err:
  220.         mov     _ax,errDPMIFailure
  221.         ERROR   ID_dpmiSetSegmentLimit
  222.  
  223. @@done:
  224.         ret
  225. ENDP
  226.  
  227.  
  228.  
  229.  
  230. ;/***************************************************************************\
  231. ;*
  232. ;* Function:    int dpmiSetSegmentAccessRights(unsigned selector,
  233. ;*                  unsigned accessRights);
  234. ;*
  235. ;* Description: Changes the access rights of a selector
  236. ;*
  237. ;* Input:       unsigned selector       selector
  238. ;*              unsigned accessRights   new access rights for the segment
  239. ;*
  240. ;* Returns:     MIDAS error code.
  241. ;*
  242. ;\***************************************************************************/
  243.  
  244. PROC    dpmiSetSegmentAccessRights      _funct  selector : _int, \
  245.                                                 accessRights : _int
  246. USES    _bx
  247.  
  248.         mov     _ax,0009h               ; DPMI function 9 - set access rights
  249.         mov     _bx,[selector]
  250.         mov     _cx,[accessRights]
  251.         int     31h
  252.         jc      @@err
  253.  
  254.         xor     _ax,_ax
  255.         jmp     @@done
  256.  
  257. @@err:
  258.         mov     _ax,errDPMIFailure
  259.         ERROR   ID_dpmiSetSegmentAccessRights
  260.  
  261. @@done:
  262.         ret
  263. ENDP
  264.  
  265.  
  266.  
  267.  
  268. ;/***************************************************************************\
  269. ;*
  270. ;* Function:    int dpmiCreateCodeAlias(unsigned codeSelector,
  271. ;*                  unsigned *selector);
  272. ;*
  273. ;* Description: Creates a data descriptor that has the same base and limit
  274. ;*              as a code segment descriptor. Use dpmiFreeDescriptor() to
  275. ;*              deallocate data descriptor.
  276. ;*
  277. ;* Input:       unsigned codeSelector   code segment selector
  278. ;*              unsigned *selector      pointer to data segment selector
  279. ;*
  280. ;* Returns:     MIDAS error code. New data selector is written to *selector.
  281. ;*
  282. ;\***************************************************************************/
  283.  
  284. PROC    dpmiCreateCodeAlias     _funct  codeSelector : _int, selector : _ptr
  285. USES    _bx
  286.  
  287.         mov     _ax,000Ah               ; 000Ah - create code alias descr.
  288.         mov     _bx,[codeSelector]
  289.         int     31h
  290.         jc      @@err
  291.  
  292. IFDEF __32__
  293.         and     eax,0FFFFh
  294. ENDIF
  295.  
  296.         LOADPTR es,_bx,[selector]       ; write selector to *selector
  297.         mov     [_esbx],_ax
  298.  
  299.         xor     _ax,_ax
  300.         jmp     @@done
  301.  
  302. @@err:
  303.         mov     _ax,errDPMIFailure
  304.         ERROR   ID_dpmiCreateCodeAlias
  305.  
  306. @@done:
  307.         ret
  308. ENDP
  309.  
  310.  
  311.  
  312.  
  313. ;/***************************************************************************\
  314. ;*
  315. ;* Function:    int dpmiAllocDOSMem(unsigned numParagraphs, unsigned *segment,
  316. ;*                  unsigned *selector);
  317. ;*
  318. ;* Description: Allocates memory from DOS free memory pool, below 1MB. Use
  319. ;*              dpmiFreeDOSMem() to deallocate.
  320. ;*
  321. ;* Input:       unsigned numParagraphs  number of paragraphs to allocate
  322. ;*              unsigned *segment       pointer to real mode segment
  323. ;*              unsigned *selector      pointer to selector
  324. ;*
  325. ;* Returns:     MIDAS error code. Real mode segment of allocated block is
  326. ;*              written to *segment. Protected mode selector for block is
  327. ;*              written to *selector.
  328. ;*
  329. ;\***************************************************************************/
  330.  
  331. PROC    dpmiAllocDOSMem         _funct  numParagraphs : _int, \
  332.                                         realSeg : _ptr, selector : _ptr
  333. USES    _bx
  334.  
  335.         mov     _ax,0100h               ; 0100h - alloc DOS memory block
  336.         mov     _bx,[numParagraphs]
  337.         int     31h
  338.         jnc     @@ok
  339.  
  340.         cmp     _ax,07h                 ; memory control blocks damaged?
  341.         je      @@mcbDamaged
  342.         cmp     _ax,08h                 ; insufficient memory?
  343.         je      @@nomemory
  344.  
  345.         mov     _ax,errDPMIFailure
  346.         jmp     @@err
  347.  
  348. @@mcbDamaged:
  349.         mov     _ax,errHeapCorrupted
  350.         jmp     @@err
  351.  
  352. @@nomemory:
  353.         mov     _ax,errOutOfMemory
  354.         jmp     @@err
  355.  
  356. @@ok:
  357. IFDEF __32__
  358.         and     eax,0FFFFh
  359.         and     edx,0FFFFh
  360. ENDIF
  361.         LOADPTR es,_bx,[realSeg]
  362.         mov     [_esbx],_ax             ; write real mode segment to *segment
  363.         LOADPTR es,_bx,[selector]
  364.         mov     [_esbx],_dx             ; write selector to *selector
  365.  
  366.         xor     _ax,_ax
  367.         jmp     @@done
  368.  
  369. @@err:
  370.         ERROR   ID_dpmiAllocDOSMem
  371.  
  372. @@done:
  373.         ret
  374. ENDP
  375.  
  376.  
  377.  
  378.  
  379. ;/***************************************************************************\
  380. ;*
  381. ;* Function:    dpmiFreeDOSMem(unsigned selector);
  382. ;*
  383. ;* Description: Deallocates memory allocated with dpmiAllocDOSMem().
  384. ;*
  385. ;* Input:       unsigned selector       selector for allocated block
  386. ;*
  387. ;* Returns:     MIDAS error code
  388. ;*
  389. ;\***************************************************************************/
  390.  
  391. PROC    dpmiFreeDOSMem          _funct  selector : _int
  392. USES    _bx
  393.  
  394.         mov     _ax,0101h               ; 0101h - free DOS memory block
  395.         mov     _dx,[selector]
  396.         int     31h
  397.         jc      @@error
  398.  
  399.         xor     _ax,_ax
  400.         jmp     @@done
  401.  
  402. @@error:
  403.         cmp     _ax,07h                 ; memory control blocks damaged?
  404.         je      @@mcbDamaged
  405.         cmp     _ax,09h                 ; incorrect segment?
  406.         je      @@badSegment
  407.  
  408.         mov     _ax,errDPMIFailure
  409.         jmp     @@err
  410.  
  411. @@mcbDamaged:
  412.         mov     _ax,errHeapCorrupted
  413.         jmp     @@err
  414.  
  415. @@badSegment:
  416.         mov     _ax,errInvalidDescriptor
  417.  
  418. @@err:
  419.         ERROR   ID_dpmiFreeDOSMem
  420.  
  421. @@done:
  422.         ret
  423. ENDP
  424.  
  425.  
  426.  
  427.  
  428. ;/***************************************************************************\
  429. ;*
  430. ;* Function:    int dpmiRealModeInt(unsigned intNum,
  431. ;*                  dpmiRealCallRegs *registers);
  432. ;*
  433. ;* Description: Simulates a real mode interrupt using DPMI service 0x0300.
  434. ;*              *register MUST contain appropriate register values for
  435. ;*              interrupt (CS:IP is ignored).
  436. ;*
  437. ;* Input:       unsigned intNum                 interrupt number
  438. ;*              dpmiRealCallRegs *registers     DPMI real mode calling struct
  439. ;*
  440. ;* Returns:     MIDAS error code. Register values returned by the interrupt
  441. ;*              are written to *registers.
  442. ;*
  443. ;\***************************************************************************/
  444.  
  445. PROC    dpmiRealModeInt         _funct  intNum : _int, registers : _ptr
  446. USES    _di,es,_bx
  447.  
  448. IFDEF __32__
  449.         mov     ax,ds
  450.         mov     es,ax
  451.         xor     ebx,ebx
  452.         xor     ecx,ecx
  453. ELSE
  454.         xor     cx,cx
  455. ENDIF
  456.  
  457.         mov     _ax,0300h               ; 0300h - simulate real mode interrupt
  458.         mov     bl,[byte intNum]
  459.         mov     bh,1                    ; reset PIC and A20 line
  460.         LOADPTR es,_di,[registers]
  461.         int     31h
  462.         jc      @@err
  463.  
  464.         ; es:_di now contains pointer to modified real mode call structure.
  465.         ; The DPMI specs do not clearly state that this is necessarily the
  466.         ; same as the original structure, so for safety we check the pointers
  467.         ; and if they differ copy the data to the original structure:
  468.  
  469. IFDEF __32__
  470.         mov     ax,es
  471.         mov     dx,ds
  472.         cmp     ax,dx
  473.         jne     @@copyregs
  474.         cmp     edi,[registers]
  475.         jne     @@copyregs
  476. ELSE
  477.         mov     ax,es
  478.         cmp     ax,[word registers+2]
  479.         jne     @@copyregs
  480.         cmp     di,[word registers]
  481.         jne     @@copyregs
  482. ENDIF
  483.  
  484.         ; es:di points to the original structure - the new register values
  485.         ; are at their place.
  486.  
  487.         xor     _ax,_ax
  488.         jmp     @@done
  489.  
  490. @@copyregs:
  491.         ; es:_di has changed - copy the new register structure to the old
  492.         ; place:
  493.         push    ds _si
  494.  
  495.         mov     _si,_di
  496.  
  497. IFDEF __32__
  498.         mov     ax,es
  499.         mov     dx,ds
  500.         mov     ds,ax
  501.         mov     es,dx
  502. ELSE
  503.         mov     ax,es                   ; ds:_si = es:_di
  504.         mov     ds,ax
  505. ENDIF
  506.         LOADPTR es,_di,[registers]
  507.         mov     _cx,SIZE dpmiRealCallRegs
  508.         cld
  509.         rep     movsb
  510.  
  511.         pop     _si ds
  512.  
  513.         xor     _ax,_ax
  514.         jmp     @@done
  515.  
  516. @@err:
  517.         mov     _ax,errDPMIFailure
  518.         ERROR   ID_dpmiRealModeInt
  519.  
  520. @@done:
  521.         ret
  522. ENDP
  523.  
  524.  
  525.  
  526.  
  527. ;/***************************************************************************\
  528. ;*
  529. ;* Function:    int dpmiLockMemory(ulong start, ulong numBytes);
  530. ;*
  531. ;* Description: Locks a region of memory to prevent it from being paged. The
  532. ;*              memory can be unlocked using dpmiUnlockMemory().
  533. ;*
  534. ;* Input:       ulong start             memory region start address
  535. ;*              ulong numBytes          memory region length in bytes
  536. ;*
  537. ;* Returns:     MIDAS error code
  538. ;*
  539. ;\***************************************************************************/
  540.  
  541. PROC    dpmiLockMemory          _funct  start : _long, numBytes : _long
  542. USES    _si,_di, _bx
  543.  
  544.         mov     _ax,0600h               ; 0600h - Lock Linear Region
  545.  
  546. IFDEF __32__
  547.         xor     ebx,ebx
  548.         xor     ecx,ecx
  549.         xor     esi,esi
  550.         xor     edi,edi
  551. ENDIF
  552.  
  553.         mov     bx,[word start+2]       ; bx:cx = start address
  554.         mov     cx,[word start]
  555.         mov     si,[word numBytes+2]    ; si:di = number of bytes
  556.         mov     di,[word numBytes]
  557.  
  558.         int     31h
  559.         jc      @@err
  560.  
  561.         xor     _ax,_ax
  562.         jmp     @@done
  563.  
  564. @@err:
  565.         mov     _ax,errDPMIFailure
  566.         ERROR   ID_dpmiLockMemory
  567.  
  568. @@done:
  569.         ret
  570. ENDP
  571.  
  572.  
  573.  
  574.  
  575. ;/***************************************************************************\
  576. ;*
  577. ;* Function:    int dpmiUnlockMemory(ulong start, ulong numBytes);
  578. ;*
  579. ;* Description: Unlocks a region of memory locked with dpmiLockMemory().
  580. ;*
  581. ;* Input:       ulong start             memory region start address
  582. ;*              ulong numBytes          memory region length in bytes
  583. ;*
  584. ;* Returns:     MIDAS error code
  585. ;*
  586. ;\***************************************************************************/
  587.  
  588. PROC    dpmiUnlockMemory        _funct  start : _long, numBytes : _long
  589. USES    _si,_di,_bx
  590.  
  591.         mov     _ax,0600h               ; 0601h - Unlock Linear Region
  592.  
  593. IFDEF __32__
  594.         xor     ebx,ebx
  595.         xor     ecx,ecx
  596.         xor     esi,esi
  597.         xor     edi,edi
  598. ENDIF
  599.  
  600.         mov     bx,[word start+2]       ; bx:cx = start address
  601.         mov     cx,[word start]
  602.         mov     si,[word numBytes+2]    ; si:di = number of bytes
  603.         mov     di,[word numBytes]
  604.  
  605.         int     31h
  606.         jc      @@err
  607.  
  608.         xor     _ax,_ax
  609.         jmp     @@done
  610.  
  611. @@err:
  612.         mov     _ax,errDPMIFailure
  613.         ERROR   ID_dpmiUnlockMemory
  614.  
  615. @@done:
  616.         ret
  617. ENDP
  618.  
  619.  
  620.  
  621. ;* $Log: dpmi.asm,v $
  622. ;* Revision 1.3  1997/01/16 18:41:59  pekangas
  623. ;* Changed copyright messages to Housemarque
  624. ;*
  625. ;* Revision 1.2  1996/08/04 11:14:32  pekangas
  626. ;* All functions now preserve _bx
  627. ;*
  628. ;* Revision 1.1  1996/05/22 20:49:33  pekangas
  629. ;* Initial revision
  630. ;*
  631.  
  632.  
  633. END